package fileExplorer;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

/** 
 *  This class contains the code for the GUI interface.
 */
public class MainGUI implements ActionListener{
/* {author=George Siegle}*/
	
	private JFrame mainFrame = new JFrame();
	private JLabel filePathLabel = new JLabel("Navigation bar: ");
	private JTextPane filePathPane = new JTextPane();
	private DefaultListModel<String> fileListModel = new DefaultListModel<String>();
	private JList<String> selectedFileDisplayList = new JList<String>(fileListModel);
	private JScrollPane selectedFileDisplayScroller;
	private DefaultListModel<String> filesThatMatchModel = new DefaultListModel<String>();
	private JList<String> fileSearchDisplayList = new JList<String>(filesThatMatchModel);
	private JScrollPane fileSearchDisplayScroller;
	private JPanel filePreviewDisplayPanel = new JPanel();
	private JScrollPane filePreviewDisplayScroller;
	private JButton browseButton = new JButton("Browse");
	private JLabel searchFileLabel = new JLabel("Search by filename: ");
	private JTextPane searchFilePane = new JTextPane();
	private JLabel selectedFileLabel = new JLabel("File browsed or folder contents:");
	private JLabel fileSearchLabel = new JLabel("Search results:");
	private JLabel filePreviewLabel = new JLabel("File preview (File must be .jpeg, .png, .gif, .bmp, or .wbmp):");
	private GridBagConstraints constraints = new GridBagConstraints();
	private JButton openFileButton = new JButton("Open File");
	private JButton filePreviewButton = new JButton("Preview File");
	private JButton searchFileButton = new JButton("Search");
	private String[] folderContents;

	/** 
	 *  This method will be used by the GUIInterface constructor to build the GUI interface.
	 */
	public void buildGUI() {
	/* {author=George Siegle}*/
		mainFrame.setTitle("File Explorer");
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.getContentPane().setLayout(new GridBagLayout());
		constraints.fill = GridBagConstraints.HORIZONTAL;
		constraints.weightx = 0.5;
		mainFrame.getContentPane().setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
		constraints.gridx = 2;
		constraints.gridy = 3;
		selectedFileDisplayList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
		selectedFileDisplayList.setLayoutOrientation(JList.VERTICAL);
		selectedFileDisplayScroller = new JScrollPane(selectedFileDisplayList);
		selectedFileDisplayScroller.setPreferredSize(new Dimension(250, 80));
		mainFrame.getContentPane().add(selectedFileDisplayScroller, constraints);
	  
		constraints.fill = GridBagConstraints.HORIZONTAL;
		constraints.weightx = 0.5;
		constraints.gridx = 2;
		constraints.gridy = 0;
		mainFrame.getContentPane().add(filePathLabel, constraints);
	  
		int filePathCondition = JComponent.WHEN_FOCUSED;
		InputMap filePathIMap = filePathPane.getInputMap(filePathCondition);
		ActionMap filePathAMap = filePathPane.getActionMap();
	  
		filePathIMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter");
		filePathAMap.put("enter", new AbstractAction() {
			private static final long serialVersionUID = 1L;
	
			@Override
			public void actionPerformed(ActionEvent event) {
				fileListModel.clear();
				filesThatMatchModel.clear();
				filePreviewDisplayPanel.removeAll();
				((JFrame)filePathPane.getTopLevelAncestor()).pack();
				if (!filePathPane.getText().equals("")) {
					FileAndFolderSearch contentSearch = new FileAndFolderSearch();
					contentSearch.setFolderOrFileSelected(filePathPane.getText());
					if (!contentSearch.isFile()) {
						contentSearch.searchForFilesAndFolders();
						folderContents = new String[contentSearch.getContents().length];
						folderContents = contentSearch.getContents();
					}
					else {
						folderContents = new String[1];
						folderContents[0] = contentSearch.getFolderOrFileSelected();
					}
					for (int folderContentsIndex = 0; folderContentsIndex < folderContents.length; folderContentsIndex++) {
						fileListModel.addElement(folderContents[folderContentsIndex]);
					}
				}
			 }
	  });
	  
	  constraints.fill = GridBagConstraints.HORIZONTAL;
	  constraints.weightx = 0.5;
	  constraints.gridx = 1;
	  constraints.gridy = 0;
	  mainFrame.getContentPane().add(filePathPane, constraints);
	  
	  browseButton.addActionListener(this);
	  constraints.fill = GridBagConstraints.HORIZONTAL;
	  constraints.weightx = 0.5;
	  constraints.gridx = 0;
	  constraints.gridy = 0;
	  mainFrame.getContentPane().add(browseButton, constraints);
	  
	  constraints.fill = GridBagConstraints.HORIZONTAL;
	  constraints.weightx = 0.5;
	  constraints.gridx = 2;
	  constraints.gridy = 1;
	  mainFrame.getContentPane().add(searchFileLabel, constraints);
	  
	  int searchFileCondition = JComponent.WHEN_FOCUSED;
	  InputMap searchFileIMap = searchFilePane.getInputMap(searchFileCondition);
	  ActionMap searchFileAMap = searchFilePane.getActionMap();
		
	  searchFileIMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter");
	  searchFileAMap.put("enter", new AbstractAction() {
		  private static final long serialVersionUID = 1L;
		  @Override
		  public void actionPerformed(ActionEvent event) {
			  fileListModel.clear();
			  filesThatMatchModel.clear(); 
			  filePreviewDisplayPanel.removeAll();
		  }
	  });
	  
	  constraints.fill = GridBagConstraints.HORIZONTAL;
	  constraints.weightx = 0.5;
	  constraints.gridx = 1;
	  constraints.gridy = 1;
	  mainFrame.getContentPane().add(searchFilePane, constraints);
	  
	  searchFileButton.addActionListener(this);
	  constraints.fill = GridBagConstraints.HORIZONTAL;
	  constraints.weightx = 0.5;
	  constraints.gridx = 0;
	  constraints.gridy = 1;
	  mainFrame.getContentPane().add(searchFileButton, constraints);
	  
	  constraints.fill = GridBagConstraints.HORIZONTAL;
	  constraints.weightx = 0.5;
	  constraints.gridx = 0;
	  constraints.gridy = 2;
	  mainFrame.getContentPane().add(filePreviewLabel, constraints);
	  
	  constraints.fill = GridBagConstraints.HORIZONTAL;
	  constraints.weightx = 0.5;
	  constraints.gridx = 1;
	  constraints.gridy = 2;
	  mainFrame.getContentPane().add(fileSearchLabel, constraints);
	  
	  constraints.fill = GridBagConstraints.HORIZONTAL;
	  constraints.weightx = 0.5;
	  constraints.gridx = 2;
	  constraints.gridy = 2;
	  mainFrame.getContentPane().add(selectedFileLabel, constraints);
	  
	  constraints.fill = GridBagConstraints.HORIZONTAL;
	  constraints.weightx = 0.5;
	  constraints.gridx = 1;
	  constraints.gridy = 3;
	  fileSearchDisplayList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
	  fileSearchDisplayList.setLayoutOrientation(JList.VERTICAL);
	  fileSearchDisplayScroller = new JScrollPane(fileSearchDisplayList);
	  fileSearchDisplayScroller.setPreferredSize(new Dimension(250, 80));
	  mainFrame.getContentPane().add(fileSearchDisplayScroller, constraints);
	  
	  constraints.fill = GridBagConstraints.HORIZONTAL;
	  constraints.weightx = 0.5;
	  constraints.gridx = 0;
	  constraints.gridy = 3;
	  filePreviewDisplayScroller = new JScrollPane(filePreviewDisplayPanel);
	  filePreviewDisplayScroller.setPreferredSize(new Dimension(250, 80));
	  mainFrame.getContentPane().add(filePreviewDisplayScroller, constraints);
	  
	  filePreviewButton.addActionListener(this);
	  constraints.fill = GridBagConstraints.HORIZONTAL;
	  constraints.weightx = 0.5;
	  constraints.gridx = 0;
	  constraints.gridy = 4;
	  mainFrame.getContentPane().add(filePreviewButton, constraints);
	  
	  openFileButton.addActionListener(this);
	  constraints.fill = GridBagConstraints.HORIZONTAL;
	  constraints.weightx = 0.5;
	  constraints.gridx = 1;
	  constraints.gridy = 4;
	  mainFrame.getContentPane().add(openFileButton, constraints);
	  
	  mainFrame.pack();
	  mainFrame.setVisible(true);
  }
	
	/** 
	 *  This method will display the file contents of the selected file name.
	 */
	private void displayFile() {
	/* {author=George Siegle}*/
		if (!selectedFileDisplayList.isSelectionEmpty()) {
			System.out.println("Hi");
			displayFilePreview(selectedFileDisplayList.getSelectedValue().toString());
		}
		else if (!fileSearchDisplayList.isSelectionEmpty()) {
			displayFilePreview(fileSearchDisplayList.getSelectedValue().toString());
		}
		else {
			JOptionPane.showMessageDialog(mainFrame, "No file selected in 'File browsed' selection box nor in 'Search results' selection box.", "Error", JOptionPane.PLAIN_MESSAGE);
		}

	}
  
	/**
	 * Method that displays the contents of the file name selected by the user in the file preview box on the main GUI.
	 * File has to be in a picture format.
	 */
	private void displayFilePreview(String fileName) {
	/* {author=George Siegle}*/
		File file = new File(fileName);
		try {
			Image fileImage = ImageIO.read(file);
			if (fileImage != null) {
				ImageIcon convertFileImage = new ImageIcon(fileImage);
				filePreviewDisplayPanel.add(new JLabel(convertFileImage));
			}
			else {
				throw new IOException();
			}
		} catch (IOException e){
			JOptionPane.showMessageDialog(mainFrame, "File could not be previewed! File must be .jpeg, .png, .gif, .bmp, or .wbmp.", "Error", JOptionPane.PLAIN_MESSAGE);
		}
	}
  
	/**
	 * Method that opens the file in its native application depending on the
	 * type of OS.
	 */
	private void openFile() {
	/* {author=George Siegle}*/
		try {
			if (!selectedFileDisplayList.isSelectionEmpty()) {
				Desktop.getDesktop().open(new File(selectedFileDisplayList.getSelectedValue().toString()));
			}
			else if(!fileSearchDisplayList.isSelectionEmpty()) {
				Desktop.getDesktop().open(new File(fileSearchDisplayList.getSelectedValue().toString()));
			}
			else {
				JOptionPane.showMessageDialog(mainFrame, "No file selected in 'File browsed' selection box nor in 'Search results' selection box.", "Error", JOptionPane.PLAIN_MESSAGE);
			}
		} catch (IOException e) {
			JOptionPane.showMessageDialog(mainFrame, "File could not be opened!", "Error", JOptionPane.PLAIN_MESSAGE);
		}
	}

	@Override
	public void actionPerformed(ActionEvent event) {
		Object action = event.getSource();
	  
		if (action == browseButton) {
			fileListModel.clear();
			filePreviewDisplayPanel.removeAll();
			new BrowseFileGUI(fileListModel, filePathPane);
		}
		else if (action == openFileButton) {
			openFile();
		}
		else if (action == searchFileButton) {
			filePreviewDisplayPanel.removeAll();
			filesThatMatchModel.clear();
			if (!searchFilePane.getText().equals("")) {
				Runnable runInBackground = new Runnable() {
					public void run() {
						new FileSearch(searchFilePane.getText(), filesThatMatchModel);
					}
				};
				new Thread(runInBackground).start();
			}
			else {
				JOptionPane.showMessageDialog(mainFrame, "'Search by filename' text box cannot be empty.", "Error", JOptionPane.PLAIN_MESSAGE);
			}
		}
		else if (action == filePreviewButton) {
			displayFile();
			mainFrame.pack();
			mainFrame.setVisible(true);
		}
	}
}